package com.zhangkunhao.notes.service;

import com.zhangkunhao.notes.dao.BaseDao;
import com.zhangkunhao.notes.dao.Dao;

import com.zhangkunhao.notes.entity.DO.Activity;

import com.zhangkunhao.notes.entity.DO.User;
import com.zhangkunhao.notes.util.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static java.util.stream.Collectors.*;


/**
 * 与功德活动业务相关的逻辑处理
 *
 * @author 张坤浩
 */
public class ActivityService {

    String sql1 = "INSERT INTO `virtue`.`activity`(`deadline`,`limit_number`,`activity_name`,`gain_virtue`) VALUES(?,?,?,?)";
    String sql2 = "SELECT `id`,`deadline`,`limit_number` as limitNumber,`activity_name` as activityName,`gain_virtue` " +
            "as gainVirtue, `participant_name` as participantName,`current_people_number` as currentPeopleNumber FROM `virtue`.`activity` where id>?";
    String sql3 = "UPDATE  `virtue`.`activity` SET `participant_name` = ?, `current_people_number`=? WHERE `activity_name` =?";

    Dao baseDao = BaseDao.getInstance();

    public ActivityService() {

    }

    public List<Activity> readAllActivities(int beginId) {
        return baseDao.queryList(sql2, Activity.class, beginId);
    }

    public String participateActivity(String activityName, User user) {
        //从数据库获取报名时间未截止的符合搜索要求的活动，活动不考虑重名的情况，所以集合中只有一个元素
        List<Activity> activityList = baseDao.queryList(sql2, Activity.class, 0).stream()
                .filter(activity -> {
                            try {
                                return activity.getDeadline().after(DateFormChangeUtil.getToday())
                                        && activity.getActivityName().equals(activityName);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                            return false;
                        }
                ).collect(toList());
        int currentPeopleNumber;
        //判断活动是否存在并且是否未达到报名限制人数
        if (activityList.size() > 0 && activityList.get(0).getLimitNumber() >= activityList.get(0).getCurrentPeopleNumber() + 1) {
            //目前活动的最新报名人数，但是后面是否更改数据库的报名人数需要判断是否为新用户首次报名
            currentPeopleNumber = activityList.get(0).getCurrentPeopleNumber() + 1;
            //从数据库获取原先活动的参与者记录，集合中只有一个元素
            List<String> record = activityList.stream().map(Activity::getParticipantName).collect(toList());
            //调用工具类判断用户是否已经报名该活动以此确定是否刷新活动的参与者记录
            String allRecord = UserUtil.judgeVisit(record, user);
            //最新的活动参与者记录与原来的不一样，即有新用户报名，这里allRecords不可能是null
            if (!allRecord.equals(record.get(0))) {
                //更新用户获得的功德量和总功德量
                user.setGainVirtue(activityList.get(0).getGainVirtue() + user.getGainVirtue());
                user.setInitVirtue(50 + user.getGainVirtue() - user.getPayVirtue());
                //调用工具类更新用户功德量到数据库
                int editInfoRow = UserUtil.editInformation(new UserService(), user);
                //更新活动参与者记录到数据库
                int updateRow = baseDao.update(sql3, allRecord, currentPeopleNumber, activityName);
                //判断更新成功与否
                return (editInfoRow > 0) && (updateRow > 0) ? "数据库用户获得功德量、活动参与者记录更新成功，用户当前获得的功德量："
                        + user.getGainVirtue() + "总功德量：" + user.getInitVirtue() : "数据库用户获得功德量、活动参与者记录更新失败";
            }
            return "你已经报名了该活动，不能重复报名哦！";
        }
        return "功德活动名称输入错误，找不到该功德活动或者活动报名限制人数已达标，请重新选择活动进行报名：";
    }

    public List<Activity> activitiesDetails(String userName) {
        UserService userService = new UserService();
        boolean judgeExistence = UserUtil.judgeExistence(userService, userName);
        //用来存放所查看的用户参加的活动的集合
        ArrayList<Activity> hisActivities = new ArrayList<>();
        if (judgeExistence) {
            //获取所有活动
            List<Activity> activityList = baseDao.queryList(sql2, Activity.class, 0);
            for (Activity activity : activityList) {
                //调用工具类判断所查看的用户是否参加过该活动
                if (UserUtil.myContains(activity.getParticipantName(), userName)) {
                    hisActivities.add(activity);
                }
            }
        }
        return hisActivities;
    }

    public String publishActivity(String activityName, String limitNumber, String gainVirtue, String deadline) {
        int updateRow;
        //调用工具类实现非空与不出现空格的判断
        boolean judge = IfValidValueJudgeUtil.judge(activityName, limitNumber, gainVirtue, deadline);
        if (!judge) {
            return "活动发布失败，数据库活动更新失败,活动的部分属性出现null或者出现空格，请重新编辑活动进行发布：";
        }
        //调用工具类对字符串进行数字类型转换
        Integer limit = StringToIntegerUtil.getInteger(limitNumber);
        Integer gain = StringToIntegerUtil.getInteger(gainVirtue);
        if (limit == -1) {
            return "活动发布失败，数据库活动更新失败,报名限制人数必须是正整数";
        }
        if (gain == -1) {
            return "活动发布失败，数据库活动更新失败,参加活动获得的功德量必须是正整数";
        }
        //对日期进行解析
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date ddl;
        try {
            ddl = sdf.parse(deadline);
        } catch (ParseException e) {
            return "活动发布时间的格式出现错误，请重新编辑活动进行发布：";
        }
        //代码执行到这里说明活动属性没有问题
        //注意传入参数的顺序与表的字段顺序稍有不同
        updateRow = baseDao.update(sql1, ddl, limitNumber, activityName, gainVirtue);
        return updateRow > 0 ? "活动发布成功，数据库活动更新成功" : "活动发布失败，数据库活动更新失败";
    }

    public String batchPublishActivities(String activityNames, String maxLimitNumber, String maxGainVirtue, String deadline, String batchActivitiesNumber) {

        //批量发布活动影响的行数
        int updateRow;
        //调用工具类实现非空与不出现空格的判断
        boolean judge = IfValidValueJudgeUtil.judge(activityNames, maxLimitNumber, maxGainVirtue, deadline);
        if (!judge) {
            return "活动发布失败，数据库活动更新失败,活动的部分属性出现null或者出现空格，请重新编辑活动进行发布：";
        }
        //调用工具类对字符串进行数字解析与判断
        Integer maxLimit = StringToIntegerUtil.getInteger(maxLimitNumber);
        Integer maxGain = StringToIntegerUtil.getInteger(maxGainVirtue);
        Integer activitiesNumber = StringToIntegerUtil.getInteger(batchActivitiesNumber);

        if (maxLimit == -1) {
            return "活动发布失败，数据库活动更新失败,报名限制人数必须是正整数";
        }
        if (maxGain == -1) {
            return "活动发布失败，数据库活动更新失败,参加活动获得的功德量必须是正整数";
        }
        if (activitiesNumber == -1) {
            return "活动发布失败，数据库活动更新失败,活动要发布的数量必须是正整数";
        }
        //对日期进行解析
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date ddl;
        try {
            ddl = sdf.parse(deadline);
        } catch (ParseException e) {
            return "活动发布时间的格式出现错误，请重新编辑活动进行发布：";
        }
        //代码执行到这里说明活动的属性没有问题
        //注意传入参数的顺序与表的字段顺序稍有不同，调用dao层
        updateRow = BaseDao.batchUpdate(sql1, activitiesNumber, ddl, maxLimit, activityNames, maxGain);
        return updateRow == activitiesNumber ? "活动发布成功，数据库批量发布的活动更新成功" + ",影响行数：" + updateRow : "活动发布失败，数据库批量发布的活动更新失败";
    }
}
